import datetime
import logging

from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
from odoo.addons.douyin_management.models.douyin_collection import COLLECTION_TYPE


_logger = logging.getLogger(__name__)


class DouyinExecWizard(models.TransientModel):
    _name = 'douyin.exec.wizard'

    exec_type = fields.Selection(
        string='操作类型',
        selection=[
            ('create_collection', '创建合集'),
            ('update_collection', '更新合集'),
            ('collection_merge', '合并视频'),
            ('collection_manual_update', '手动更新合集'),
            ('create_fake_collection', '创建伪合集'),
            ('query_video_episode', '根据时间查询所属集数'),
            ('export_collection_ep_discord', '导出合集指定集数'),
            ('temp_action', '临时按钮')
        ],
        required=True
    )
    export_collection_id = fields.Many2one(comodel_name='douyin.collection', string='导出合集')
    export_start_ep = fields.Integer(string='开始集数')
    export_end_ep = fields.Integer(string='结束集数')
    manual_collection_id = fields.Many2one(
        comodel_name='douyin.collection',
        string='手动更新合集'
    )
    # 置顶视频会自动添加，如果有置顶视频需要从总数中减去，也就是说不考虑置顶视频
    # 置顶图文不会自动添加
    manual_update_count = fields.Integer(string='手动更新数量')
    manual_update_type = fields.Selection(
        string='手动更新类型',
        selection=[('range', '选取片段'), ('delete', '清除')],
        default='range'
    )
    collection_line_ids = fields.One2many(
        comodel_name='collection.alias.line',
        inverse_name='douyin_exec_id',
        string='创建的合集'
    )
    manual_update_info_line_ids = fields.One2many(
        comodel_name='manual.update.info.line',
        inverse_name='douyin_exec_id',
        string='手动合并信息'
    )
    # 伪合集信息
    fake_collection_alias = fields.Char(string='别名')
    fake_collection_is_finished = fields.Boolean(string='已完结')
    fake_collection_categ_id = fields.Many2one(comodel_name='douyin.collection.categ', string='视频类别')
    fake_collection_type = fields.Selection(string='视频类型', selection=COLLECTION_TYPE)
    fake_channel_name = fields.Char(string='Discord频道名称')
    sec_uid = fields.Char(string='Sec UID')
    # 视频所属时长
    video_query_time = fields.Integer(string='查询时长')
    query_collection_id = fields.Many2one(
        comodel_name='douyin.collection',
        string='查询时长的合集'
    )

    def action_query_video_by_time(self):
        '''根据时长查询所属集数'''
        self.ensure_one()
        sum_duration = 0
        query_time = self.video_query_time * 1000
        for video in self.query_collection_id.video_ids:
            sum_duration += video.duration
            if sum_duration > query_time:
                _logger.info(f'所属集数：{video.current_episode} 集')
                break

    def action_merge_ready_collection(self):
        '''合并已准备好的合集'''
        self.env['douyin.merge'].search([('state', '=', 'ready')]).action_merge_collection()

    def action_create_collection(self):
        '''通过向导创建合集'''
        # 先判断合集是否已经存在
        collection_obj = self.env['douyin.collection']
        mix_ids = self.collection_line_ids.mapped('mix_id')
        collections = collection_obj.search([('mix_id', 'in', mix_ids)])
        if collections:
            collection_names = ','.join(collections.mapped('mix_name'))
            collection_mix_ids = ','.join(collections.mapped('mix_id'))
            raise UserError(f'合集：{collection_names} 已经存在，Mix ID: {collection_mix_ids}')
        new_collection_values = self.collection_line_ids.mapped(
            lambda r: {
                'mix_id': r.mix_id,
                'channel_name': r.channel_name,
                'alias': r.alias,
                'is_finished': r.is_finished,
                'categ_id': r.categ_id.id,
                'collection_type': r.collection_type
            }
        )
        new_collections = collection_obj.create(new_collection_values)

        task_sequence = self.env['celery.task.sequence'].create({
            'sequence_type': 'create_collection'
        })
        self.env['celery.task'].create({
            'task_type': 'create_collection',
            'sequence_id': task_sequence.id,
            'collection_ids': [(6, 0, new_collections.ids)]
        })
        task_sequence.action_run_sequence()

    def action_update_collection(self):
        '''更新所有未完结合集'''
        self.ensure_one()
        update_collections = self.env['douyin.collection'].search([
            ('is_finished', '=', False),
            ('is_fake_collection', '=', False),
            ('is_interrupt', '=', False)
        ])
        update_collections.action_update_collection()

    def action_temp(self):
        all_collections = self.env['douyin.collection'].search([])
        for c in all_collections:
            c.channel_name = c.alias

    def _create_manual_update_task_sequence(self, collection):
        task_sequence = self.env['celery.task.sequence'].create({
            'sequence_type': self.exec_type
        })
        new_task_vals = {
            'task_type': self.exec_type,
            'manual_update_type': self.manual_update_type,
            'sequence_id': task_sequence.id,
            'manual_update_collection_id': collection.id,
            'manual_update_count': self.manual_update_count,
            'manual_update_info_ids': self.manual_update_info_line_ids.mapped(lambda r: (0, 0, {
                'start': r.start,
                'end': r.end,
                'append_sequence': r.append_sequence,
                'reverse': r.reverse,
                'note': r.note,
                'manual_update_type': self.manual_update_type
            }))
        }
        if self.exec_type == 'create_fake_collection':
            new_task_vals.update({'sec_uid': self.sec_uid})
        task = self.env['celery.task'].create(new_task_vals)
        return task_sequence

    def action_update_collection_manual(self):
        '''将作者未加入合集的视频手动添加到合集中
        * 添加视频成功后，需要更新合集的集数
            * 手动更新的合集集数在一段时间内都会大于实际的合集集数，自动更新时不会产生更新任务
        '''
        task_sequence = self._create_manual_update_task_sequence(self.manual_collection_id)
        task_sequence.action_run_sequence()

    def action_create_fake_collection(self):
        '''创建伪合集'''
        self.ensure_one()
        new_collection_value = {
            'alias': self.fake_collection_alias,
            'is_finished': self.fake_collection_is_finished,
            'categ_id': self.fake_collection_categ_id.id,
            'collection_type': self.fake_collection_type,
            'channel_name': self.fake_channel_name,
            'is_fake_collection': True
        }
        fake_collection = self.env['douyin.collection'].create(new_collection_value)
        task_sequence = self._create_manual_update_task_sequence(fake_collection)
        task_sequence.action_run_sequence()

    def action_export_collection_ep_discord(self):
        sorted_videos = self.export_collection_id.video_ids.sorted(lambda v: v.current_episode)
        seq = f'\r\n{"-"*80}\r\n'
        update_content = sorted_videos.mapped(lambda v: f'  {v.current_episode}集 {v.title}: {v.video_url}')
        _logger.info('\r\n'+seq.join(update_content[self.export_start_ep-1: self.export_end_ep]))

class CollectionAliasLine(models.TransientModel):
    _name = 'collection.alias.line'

    mix_id = fields.Char(string='Mix ID', required=True)
    alias = fields.Char(string='别名', required=True)
    channel_name = fields.Char(string='频道名称', required=True)
    categ_id = fields.Many2one(
        comodel_name='douyin.collection.categ',
        string='合集分类',
        required=True
    )
    is_finished = fields.Boolean(string='已完结', default=False)
    collection_type = fields.Selection(string='视频类型', selection=COLLECTION_TYPE, required=True)
    douyin_exec_id = fields.Many2one(comodel_name='douyin.exec.wizard', string='向导')


class ManualUpdateInfoLine(models.TransientModel):
    '''
    手动合并需要提供的信息
    '''
    _name = 'manual.update.info.line'
    _inherit = ['manual.update.info.mix']

    douyin_exec_id = fields.Many2one(
        comodel_name='douyin.exec.wizard',
        string='向导'
    )